package com.arrogames.rgblabyrinth.game.targeting {
	import ash.core.Engine;
	import ash.tools.ListIteratingSystem;
	
	import com.arrogames.lib.ash.animation.Animation;
	import com.arrogames.lib.ash.animation.IAnimatable;
	import com.arrogames.lib.ash.movement.Direction;
	import com.arrogames.lib.ash.movement.Speed;
	import com.arrogames.lib.ash.rendering.Display;
	import com.arrogames.rgblabyrinth.game.GameState;
	import com.arrogames.tmx.CoordinateUtil;
	
	import flash.geom.Point;
	
	import starling.display.DisplayObjectContainer;
	import starling.events.Touch;
	import starling.events.TouchEvent;
	import starling.events.TouchPhase;
	
	/**
	 * System that moves the player to the target.
	 * @author Robin
	 * 
	 */
	public class TargetingSystem extends ListIteratingSystem {
		private var SPEED:Number = 3;
		private var container:DisplayObjectContainer;
		private var player:PlayerNode;

		private var gameState:GameState;
		
		public function TargetingSystem(container:DisplayObjectContainer) {
			super(TargetNode, targetNodeUpdated, targetNodeAdded, targetNodeRemoved);
			this.container = container;
			container.addEventListener(TouchEvent.TOUCH, onTouch);
		}
		
		override public function addToEngine(engine:Engine):void {
			super.addToEngine(engine);
			engine.getNodeList(PlayerNode).nodeAdded.add(onPlayerAdded);
			
			gameState = engine.getEntityByName(GameState.GAMESTATE).get(GameState) as GameState;
		}
		
		private function onPlayerAdded(node:PlayerNode):void {
			player = node;
		}		
		
		private function onTouch(event:TouchEvent):void {
			var touch:Touch = event.getTouch(container, TouchPhase.ENDED);
			if (touch && player != null) {
				var localPos:Point = touch.getLocation(container);
				var isoPos:Point = CoordinateUtil.screenToIsometric(localPos.x-gameState.halfMapWidth, localPos.y, gameState.tileWidth, gameState.tileHeight);
				isoPos.x = Math.floor(isoPos.x);
				isoPos.y = Math.floor(isoPos.y);
				if (isoPos.x != Math.floor(player.position.x) || isoPos.y != Math.floor(player.position.y)) {
					if (player.entity.has(TargetLocation)) {
						player.entity.remove(TargetLocation);
					}
					player.entity.add(new TargetLocation(isoPos.x, isoPos.y));
				}
			}
		}
		
		private function targetNodeAdded(node:TargetNode):void {
			var vx:Number = node.target.x - node.position.x;
			var vy:Number = node.target.y - node.position.y;
			var angle:Number = Math.atan2(vx,vy) * (180 / Math.PI);
			
			node.entity.add(new Speed(SPEED));
			node.entity.add(new Direction(angle));
			var display:Display = node.entity.get(Display) as Display;
			node.entity.add(new Animation(display.graphic as IAnimatable));
		}
		
		private function targetNodeRemoved(node:TargetNode):void {
			node.entity.remove(Speed);
			node.entity.remove(Direction);
			node.entity.remove(Animation);
		}
		
		private function targetNodeUpdated(node:TargetNode, time:Number):void {
			if (near(node.target.x, node.position.x, .03) && near(node.target.y, node.position.y, .03)) {
				node.position.x = node.target.x;
				node.position.y = node.target.y;
				
				node.entity.remove(TargetLocation);
			}
		}
		
		private function near(x1:Number, x2:Number, offset:Number):Boolean {
			return x1-x2 > -offset && x1-x2 < offset;
		}
		
	}
}